//
// Created by antler on 2019/1/8.
//

#ifndef LUA_ZIPUTILS_H
#define LUA_ZIPUTILS_H

#include <string>
#include <vector>
#include <unordered_map>

#include "unzip.h"

struct ZipEntryInfo {
    unz64_file_pos pos;
    ZPOS64_T uncompressed_size;
    bool subFile;
};

using ResizableBuffer = std::vector<unsigned char>;
using FileListContainer = std::unordered_map<std::string, ZipEntryInfo>;

class ZipFile {
protected:
    class ZipFilePrivate {
    public:
        unzFile zipFile;
        unzFile zipSubFile;
        FileListContainer fileList;
    };

public:
    static ZipFile *createWithBuffer(const void *buffer, unsigned long size);

public:
    ~ZipFile();

    bool initWithBuffer(const void *buffer, unsigned long size);

    /**
    * Regenerate accessible file list based on a new filter string.
    *
    * @param filter New filter string (first part of files names)
    * @return true whenever zip file is open successfully and it is possible to locate
    *              at least the first file, false otherwise
    *
    */
    bool setFilter(unzFile unzip, bool subZip, const std::string &filter);

    bool fileExists(const std::string &fileName) const;

    /**
    * Get resource file data from a zip file.
    * @param fileName File name
    * @param[out] buffer If the file read operation succeeds, if will contain the file data.
    * @return True if successful.
    */
    bool getFileData(const std::string &fileName, ResizableBuffer &buffer);

    bool getFileList(FileListContainer &fileList) const;

protected:
    ZipFile();

    ZipFilePrivate *_data;
};


#endif //LUA_ZIPUTILS_H